﻿using System.Collections.Generic;
using System.Web;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Localization;
using Nop.Core.Events;
using Nop.Data;
using Nop.Services.Catalog;
using Nop.Services.Localization;
using Nop.Services.Messages;

namespace Nop.Plugin.Pricing.PreciousMetals.Services
{
    public class PreciousMetalsProductService : ProductService
    {
        private readonly IPriceCalculationService _priceCalculationService;
        private readonly IPreciousMetalsDetailService _preciousMetalsDetailService;
        private readonly IWorkContext _workContext;

        #region Constructor
        public PreciousMetalsProductService(
            ICacheManager cacheManager, IRepository<Product> productRepository, IRepository<ProductVariant> productVariantRepository,
            IRepository<RelatedProduct> relatedProductRepository, IRepository<CrossSellProduct> crossSellProductRepository,
            IRepository<TierPrice> tierPriceRepository, IRepository<ProductPicture> productPictureRepository,
            IRepository<LocalizedProperty> localizedPropertyRepository, IProductAttributeService productAttributeService,
            IProductAttributeParser productAttributeParser, ILanguageService languageService, IWorkflowMessageService workflowMessageService,
            IDataProvider dataProvider, IDbContext dbContext, LocalizationSettings localizationSettings, CommonSettings commonSettings,
            IEventPublisher eventPublisher, IPriceCalculationService priceCalculationService, IPreciousMetalsDetailService preciousMetalsDetailService,
            IWorkContext workContext)
            : base(cacheManager, productRepository, productVariantRepository, relatedProductRepository, crossSellProductRepository,
            tierPriceRepository, productPictureRepository, localizedPropertyRepository, productAttributeService, productAttributeParser,
            languageService, workflowMessageService, dataProvider, dbContext, localizationSettings, commonSettings, eventPublisher)
        {
            _priceCalculationService = priceCalculationService;
            _preciousMetalsDetailService = preciousMetalsDetailService;
            _workContext = workContext;
        }
        #endregion

        public override IList<TierPrice> GetTierPricesByProductVariantId(int productVariantId)
        {
            var tierPrices = base.GetTierPricesByProductVariantId(productVariantId);

            // when on the admin site, make sure to just return the raw values
            if (HttpContext.Current.Request.Url.AbsolutePath.ToLower().Contains("/admin/"))
                return tierPrices;

            // see if this product has precious metal tier pricing
            var detail = _preciousMetalsDetailService.Get(productVariantId);
            if (detail == null || detail.TierPriceType == (int)PreciousMetalsTierPriceType.DoNotUse)
                return tierPrices;

            // get the precious metal price calc service
            var priceCalculationService = (PreciousMetalsPriceCalculationService)this._priceCalculationService;

            List<TierPrice> newTierPrices = new List<TierPrice>();

            // calculate the tier price on each item
            foreach (var tierPrice in tierPrices)
            {
                var newTierPrice = new TierPrice()
                {
                    CustomerRole = tierPrice.CustomerRole,
                    CustomerRoleId = tierPrice.CustomerRoleId,
                    Id = tierPrice.Id,
                    ProductVariant = tierPrice.ProductVariant,
                    ProductVariantId = tierPrice.ProductVariantId,
                    Quantity = tierPrice.Quantity,
                    Price = priceCalculationService.GetMetalTierPrice(tierPrice.ProductVariant, _workContext.CurrentCustomer, tierPrice.Quantity, detail)
                };
                newTierPrices.Add(newTierPrice);
            }

            return newTierPrices;
        }
    }
}
